import { defineStore } from 'pinia';
import usePlayerConfigStore from './usePlayerConfigStore';
import useSoundStore from './useSoundStore';

let groupIdSeed = 1;

const useStore = defineStore('acfFeedback', {
	state: () => {
		return {
			gridCol: 6,
			gridRow: 4,
			gridMap: [],
			group: new Map()
		}
	},
	getters: {},
	actions: {
		init() {
			for (let y = 0; y < this.gridRow; y++) {
				this.gridMap[y] = [];
				for (let x = 0; x < this.gridCol; x++) {
					this.fillCell(x, y);
				}
			}
		},
		createGroup(sound, keyboard = null) {
			const seed = groupIdSeed++;
			const id = Symbol(seed);
			const name = `g - ${seed}`;
			const group = {
				id, name,
				cells: new Set(),
				sound: sound || useSoundStore().defaultOscSound,
				keyboard
			};
			this.group.set(id, group);
			return group;
		},
		fillCell(x, y) {
			const group = this.createGroup(useSoundStore().oscSounds[y * this.gridCol + x]);
			const cell = {
				groupId: group.id, groupName: group.name,
				x, y, disabled: false
			}
			this.gridMap[y][x] = cell;
			group.cells.add(cell);
			return cell;
		},
		disabledCell(x, y) {
			this.gridMap[y][x].disabled = true;
		},
		enabledCell(x, y) {
			this.gridMap[y][x].disabled = false;
		},
		splitCell(x, y) {
			const group = this.createGroup(this.oscSounds[y * this.gridCol + x]);
			this.mergeCell(group.id, x, y);
		},
		mergeCell(groupId, x, y) {
			const cell = this.gridMap[y][x];
			if (cell.groupId === groupId) return;
			const currentGroup = this.group.get(cell.groupId);
			currentGroup.cells.delete(cell);
			if (!currentGroup.cells.size) {
				this.group.delete(currentGroup.id);
			}
			if (groupId) {
				const nextGroup = this.group.get(groupId);
				cell.groupId = nextGroup.id;
				cell.groupName = nextGroup.name;
				nextGroup.cells.add(cell);
			}
		},
		changeGridRow(row) {
			if (row < this.gridRow) {
				for (let y = row; y < this.gridRow; y++) {
					for (let x = 0; x < this.gridCol; x++) {
						this.mergeCell(null, x, y);
					}
				}
				this.gridMap.length = row;
			} else {
				for (let y = this.gridRow; y < row; y++) {
					this.gridMap[y] = [];
					for (let x = 0; x < this.gridCol; x++) {
						this.fillCell(x, y);
					}
				}
			}
			this.gridRow = row;
		},
		changeGridCol(col) {
			if (col < this.gridCol) {
				for (let y = 0; y < this.gridRow; y++) {
					for (let x = col; x < this.gridCol; x++) {
						this.mergeCell(null, x, y);
					}
					this.gridMap[y].length = col;
				}
			} else {
				for (let y = 0; y < this.gridRow; y++) {
					for (let x = this.gridCol; x < col; x++) {
						this.fillCell(x, y);
					}
				}
			}
			this.gridCol = col;
		},
		changeGroupSound(groupId, soundId) {
			this.group.get(groupId).sound = useSoundStore().allSounds.find(sound => sound.id === soundId);
		},
		bindKeyboard(groupId, kbCode) {
			this.group.forEach(group => {
				if (group.id != groupId && group.keyboard == kbCode) {
					group.keyboard = null;
				}
			})
			this.group.get(groupId).keyboard = kbCode;
		},
		unbindKeyboard(groupId) {
			this.group.get(groupId).keyboard = null;
		},
		dispatchSoundByCell(x, y) {
			const cell = this.gridMap[y][x];
			if (cell.disabled) return;
			return useSoundStore().vocalSound(this.group.get(cell.groupId)?.sound);
		},
		dispatchSoundByKeyboard(kbCode) {
			let node;
			this.group.forEach(group => {
				if (group.keyboard === kbCode && [...group.cells].some(cell => !cell.disabled)) {
					node = useSoundStore().vocalSound(group.sound);
				}
			})
			return node;
		}
	}
})

export default useStore;